from appium.webdriver import WebElement
from loguru import logger
from selenium.common import StaleElementReferenceException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from basic.basedriver import DRIVER


class BasePage:
    """
    页面基础类，封装了页面操作的通用方法
    所有具体页面类都应继承此类，以复用基础操作方法
    """
    def __init__(self):
        """
        初始化方法，获取全局的 Appium 驱动实例
        """
        # 将全局的 DRIVER 实例赋值给当前页面的 driver 属性
        self.driver = DRIVER

    def locator(self, loc, wait: int = None, freq: int = 0.5) -> WebElement | bool:
        """
        元素定位方法，支持直接定位和显式等待定位两种方式
        :param loc: 元素定位表达式，格式为(定位策略, 定位值)，如("id", "com.example:id/btn")
        :param wait: 显式等待时间（秒），为 None 时使用直接定位
        :param freq: 显式等待的轮询间隔时间（秒），默认 0.5 秒
        :return: 找到的 WebElement 对象，未找到时可能返回 None
        """
        # 如果未指定等待时间，直接使用驱动的 find_element 方法定位元素
        if wait is None:
            return self.driver.find_element(*loc)
        # 如果指定了等待时间，使用显式等待方式定位元素
        else:
            # 创建 WebDriverWait 实例，设置等待时间和轮询间隔
            # 忽略 StaleElementReferenceException 异常（元素过时引用异常）
            return WebDriverWait(
                self.driver,
                wait,
                freq,
                ignored_exceptions=[StaleElementReferenceException]
            ).until(
                # 等待元素可被选中（此处原逻辑可能存在问题，通常应使用 element_to_be_clickable）
                EC.element_to_be_selected(loc)
            )

    def click(self, loc, wait: int = None, freq: int = 0.5) -> None:
        """
        元素点击方法，先定位元素再执行点击操作
        :param loc: 元素定位表达式，格式同上
        :param wait: 显式等待时间（秒）
        :param freq: 显式等待的轮询间隔时间（秒）
        """
        # 记录点击操作的日志，包含定位表达式
        logger.info(f"点击元素{loc}")
        # 调用 locator 方法定位元素，并执行 click() 方法
        self.locator(loc, wait, freq).click()

    def click_by_text(self, text, wait: int = None, freq: int = 0.5) -> None:
        """
        通过文本内容定位并点击元素（适用于 Android 原生应用）
        :param text: 元素的文本内容
        :param wait: 显式等待时间（秒）
        :param freq: 显式等待的轮询间隔时间（秒）
        """
        # 构建 XPath 定位表达式，通过 @text 属性匹配文本内容
        loc = ("xpath", f'//*[@text="{text}"]')
        # 记录通过文本点击的日志
        logger.info(f"点击文本{loc}")
        # 调用 click 方法执行点击操作
        self.click(loc, wait, freq)
    def Redmi_phone(self):
        self.click_by_text("REDMI手机")
